package com.my.magicApi.interceptor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.my.magicApi.token.SysTokenService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.ssssssss.magicapi.core.interceptor.RequestInterceptor;
import org.ssssssss.magicapi.core.model.ApiInfo;
import org.ssssssss.magicapi.core.model.JsonBean;
import org.ssssssss.magicapi.core.model.Options;
import org.ssssssss.script.MagicScriptContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * 自定义请求拦截器，可实现鉴权
 * https://ssssssss.org/magic-api/pages/senior/interceptor/
 * @see RequestInterceptor
 */
@Slf4j
public class CustomRequestInterceptor implements RequestInterceptor {


	private static final Logger logger = LoggerFactory.getLogger(CustomRequestInterceptor.class);

	@Autowired
	SysTokenService sysTokenService;

	/**
	 * 接口请求之前
	 * @param info	接口信息
	 * @param context	脚本变量信息
	 */
	@Override
	public Object preHandle(ApiInfo info, MagicScriptContext context, HttpServletRequest request, HttpServletResponse response) throws Exception {
		String authorization = request.getHeader("Authorization");
		if(StrUtil.isBlank(authorization)){
			return new JsonBean<>(401, "需要添加请求头Authorization");
		}
		JSONObject user = null;
		try {
			user = sysTokenService.getLoginUser(authorization);
		}catch (Exception e){
			e.printStackTrace();
			log.info("token校验失败："+e.getMessage());
			return new JsonBean<>(401, "token失效，请重新登录");
		}

		//能获取到用户信息则放入SecurityContext
		if (!Objects.isNull(user)){
			UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
//					user.getJSONObject("user"),
					user,
					null);
			authenticationToken.setDetails(
					new WebAuthenticationDetailsSource().buildDetails(request));
			SecurityContextHolder.getContext().setAuthentication(authenticationToken);
		}
		JSONObject user1 = user.getJSONObject("user");
		log.info("{} 请求接口：{}",
				"userId:"+user.getStr("userId")+
						",deptid:"+user.getStr("deptId")+
						",userName:"+user1.getStr("userName"),
				info.getName());
		// 接口选项配置了需要登录
		if ("true".equals(info.getOptionValue(Options.REQUIRE_LOGIN))) {
			if (user == null) {
				return new JsonBean<>(401, "用户未登录");
			}
		}
		String role = info.getOptionValue(Options.ROLE);
		if (StringUtils.isNotBlank(role)/* && user.hasRole(role)*/) {
			return new JsonBean<>(403, "用户权限不足");
		}
		String permission = info.getOptionValue(Options.PERMISSION);
		if (StringUtils.isNotBlank(permission)/* && user.hasPermission(permission)*/) {
			return new JsonBean<>(403, "用户权限不足");
		}
		return null;
	}

	/**
	 * 接口执行之后
	 * @param info	接口信息
	 * @param context	变量信息
	 * @param value 即将要返回到页面的值
	 */
	@Override
	public Object postHandle(ApiInfo info, MagicScriptContext context, Object value, HttpServletRequest request, HttpServletResponse response) throws Exception {
		logger.info("{} 执行，路径-{}，head:{}参数：parameters:{}===body:{},返回结果:{}",
				info.getName(),
				context.getScriptName(),
				context.getRootVariables(),
				request.getQueryString(),
				info.getRequestBody(),
				value);
//		logger.info("{} 执行完毕，返回结果:{}", info.getName(), value);
		return null;
	}
}
